package org.dromara.nursing.service.impl;

import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.dromara.nursing.domain.bo.ContactBo;
import org.dromara.nursing.domain.vo.ContactVo;
import org.dromara.nursing.domain.Contact;
import org.dromara.nursing.mapper.ContactMapper;
import org.dromara.nursing.service.IContactService;
import org.dromara.nursing.domain.vo.ElderBasicVo;
import org.springframework.context.ApplicationContext;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.Map;
import java.util.Collection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Comparator;
import java.util.stream.Collectors;

/**
 * 联系人信息Service业务层处理
 *
 * @author Xue
 * @date 2025-03-18
 */
@RequiredArgsConstructor
@Service
public class ContactServiceImpl implements IContactService {

    private final ContactMapper baseMapper;

    @Autowired
    private ApplicationContext applicationContext;

    /**
     * 查询联系人信息
     *
     * @param contactId 主键
     * @return 联系人信息
     */
    @Override
    public ContactVo queryById(Long contactId){
        ContactVo contact = baseMapper.selectVoById(contactId);

        // 基于角色的数据权限过滤
        // 定义角色常量
        final String FAMILY_ROLE_KEY = "jiashu";
        final String ADMIN_ROLE_KEY = "admin_ms";
        final String SUPER_ADMIN_ROLE_KEY = "admin";

        boolean isFamilyUser = cn.dev33.satoken.stp.StpUtil.hasRole(FAMILY_ROLE_KEY);
        boolean isAdminUser = cn.dev33.satoken.stp.StpUtil.hasRole(ADMIN_ROLE_KEY) ||
                             cn.dev33.satoken.stp.StpUtil.hasRole(SUPER_ADMIN_ROLE_KEY);

        // 如果是家属用户，只能查看自己的联系人信息
        if (isFamilyUser && !isAdminUser && contact != null) {
            Long userId = org.dromara.common.satoken.utils.LoginHelper.getUserId();
            if (userId != null) {
                // 检查该联系人是否属于当前用户
                if (contact.getContactUserId() == null || !contact.getContactUserId().equals(userId)) {
                    // 如果没有权限访问，返回null
                    return null;
                }
            }
        }

        return contact;
    }

    /**
     * 分页查询联系人信息列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 联系人信息分页列表
     */
    @Override
    public TableDataInfo<ContactVo> queryPageList(ContactBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<Contact> lqw = buildQueryWrapper(bo);
        Page<ContactVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的联系人信息列表
     *
     * @param bo 查询条件
     * @return 联系人信息列表
     */
    @Override
    public List<ContactVo> queryList(ContactBo bo) {
        LambdaQueryWrapper<Contact> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<Contact> buildQueryWrapper(ContactBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<Contact> lqw = Wrappers.lambdaQuery();
        lqw.orderByAsc(Contact::getContactId);
        lqw.like(StringUtils.isNotBlank(bo.getContactName()), Contact::getContactName, bo.getContactName());
        lqw.like(StringUtils.isNotBlank(bo.getElderName()), Contact::getElderName, bo.getElderName());

        // 基于角色的数据权限过滤
        // 定义角色常量
        final String FAMILY_ROLE_KEY = "jiashu";
        final String ADMIN_ROLE_KEY = "admin_ms";
        final String SUPER_ADMIN_ROLE_KEY = "admin";

        boolean isFamilyUser = cn.dev33.satoken.stp.StpUtil.hasRole(FAMILY_ROLE_KEY);
        boolean isAdminUser = cn.dev33.satoken.stp.StpUtil.hasRole(ADMIN_ROLE_KEY) ||
                             cn.dev33.satoken.stp.StpUtil.hasRole(SUPER_ADMIN_ROLE_KEY);

        // 如果是家属用户，只能查看自己关联的联系人信息
        if (isFamilyUser && !isAdminUser) {
            Long userId = org.dromara.common.satoken.utils.LoginHelper.getUserId();
            if (userId != null) {
                // 家属用户只能查看自己的联系人信息
                lqw.eq(Contact::getContactUserId, userId);
            } else {
                // 如果无法获取用户ID，则不返回任何数据
                lqw.eq(Contact::getContactId, -1);
            }
        }

        return lqw;
    }

    /**
     * 新增联系人信息
     *
     * @param bo 联系人信息
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(ContactBo bo) {
        Contact add = MapstructUtils.convert(bo, Contact.class);
        validEntityBeforeSave(add);

        // 自动设置contactUserId为当前登录用户ID
        if (add.getContactUserId() == null) {
            Long userId = org.dromara.common.satoken.utils.LoginHelper.getUserId();
            if (userId != null) {
                add.setContactUserId(userId);
            }
        }

        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setContactId(add.getContactId());
        }
        return flag;
    }

    /**
     * 修改联系人信息
     *
     * @param bo 联系人信息
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(ContactBo bo) {
        Contact update = MapstructUtils.convert(bo, Contact.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(Contact entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 为老人创建联系人记录
     *
     * @param elderId 老人ID
     * @param elderName 老人姓名
     * @param userId 用户ID
     * @return 是否创建成功
     */
    @Override
    public Boolean createContactForElder(Long elderId, String elderName, Long userId) {
        try {
            if (elderId == null || StringUtils.isEmpty(elderName) || userId == null) {
                return false;
            }

            // 创建联系人记录
            Contact contact = new Contact();
            contact.setElderId(elderId);
            contact.setElderName(elderName);
            contact.setContactName(org.dromara.common.satoken.utils.LoginHelper.getUsername());
            contact.setContactUserId(userId);
            contact.setIsEmergencyContact(1L); // 设为紧急联系人
            contact.setRelationship("家属");

            // 保存联系人记录
            return baseMapper.insert(contact) > 0;
        } catch (Exception e) {
            // 记录异常但不影响老人信息保存
            org.slf4j.LoggerFactory.getLogger(ContactServiceImpl.class)
                .error("自动创建联系人记录失败", e);
            return false;
        }
    }

    /**
     * 校验并批量删除联系人信息信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteByIds(ids) > 0;
    }

    /**
     * 获取去重后的联系人列表（当前用户只显示一次）
     *
     * @param bo 查询条件
     * @return 去重后的联系人列表
     */
    @Override
    public List<ContactVo> getUniqueContactList(ContactBo bo) {
        // 获取当前登录用户ID
        Long currentUserId = org.dromara.common.satoken.utils.LoginHelper.getUserId();
        String currentUsername = org.dromara.common.satoken.utils.LoginHelper.getUsername();

        // 获取所有联系人列表
        List<ContactVo> allContacts = queryList(bo);

        // 如果当前用户不是家属用户或者没有获取到用户ID，直接返回所有联系人
        final String FAMILY_ROLE_KEY = "jiashu";
        boolean isFamilyUser = cn.dev33.satoken.stp.StpUtil.hasRole(FAMILY_ROLE_KEY);

        if (!isFamilyUser || currentUserId == null) {
            return allContacts;
        }

        // 分离当前用户的联系人记录和其他联系人记录
        List<ContactVo> currentUserContacts = new ArrayList<>();
        List<ContactVo> otherContacts = new ArrayList<>();

        for (ContactVo contact : allContacts) {
            // 判断是否是当前用户自己的联系人记录
            if (contact.getContactUserId() != null &&
                contact.getContactUserId().equals(currentUserId) &&
                currentUsername.equals(contact.getContactName())) {
                // 当前用户的联系人记录
                currentUserContacts.add(contact);
            } else {
                // 其他联系人记录
                otherContacts.add(contact);
            }
        }

        // 从当前用户的联系人记录中选择一条（最新的一条）
        ContactVo currentUserContact = null;
        if (!currentUserContacts.isEmpty()) {
            // 按ID排序，选择最大ID（假设ID越大越新）
            currentUserContact = currentUserContacts.stream()
                .max(Comparator.comparing(ContactVo::getContactId))
                .orElse(null);
        }

        // 合并结果
        List<ContactVo> result = new ArrayList<>();
        if (currentUserContact != null) {
            result.add(currentUserContact);
        }
        result.addAll(otherContacts);

        return result;
    }

    /**
     * 创建联系人与老人的关联关系
     *
     * @param contactId 联系人ID
     * @param elderId 老人ID
     * @return 是否创建成功
     */
    @Override
    public Boolean createContactElderRelation(Long contactId, Long elderId) {
        try {
            if (contactId == null || elderId == null) {
                return false;
            }

            // 获取联系人信息
            Contact contact = baseMapper.selectById(contactId);
            if (contact == null) {
                return false;
            }

            // 更新联系人的老人ID和老人姓名
            // 获取老人信息
            // 使用ApplicationContext获取ElderBasicService，避免循环依赖
            org.dromara.nursing.service.IElderBasicService elderBasicService =
                applicationContext.getBean(org.dromara.nursing.service.IElderBasicService.class);
            ElderBasicVo elder = elderBasicService.queryById(elderId);
            if (elder == null) {
                return false;
            }

            // 更新联系人信息
            contact.setElderId(elderId);
            contact.setElderName(elder.getElderName());

            // 保存更新
            return baseMapper.updateById(contact) > 0;
        } catch (Exception e) {
            // 记录异常
            org.slf4j.LoggerFactory.getLogger(ContactServiceImpl.class)
                .error("创建联系人与老人关联关系失败", e);
            return false;
        }
    }

    /**
     * 验证老人身份证号
     *
     * @param elderId 老人ID
     * @param idCard 身份证号
     * @return 验证结果
     */
    @Override
    public Boolean verifyElderIdCard(Long elderId, String idCard) {
        try {
            if (elderId == null || idCard == null) {
                return false;
            }

            // 使用ApplicationContext获取ElderBasicService，避免循环依赖
            org.dromara.nursing.service.IElderBasicService elderBasicService =
                applicationContext.getBean(org.dromara.nursing.service.IElderBasicService.class);

            // 使用不进行权限过滤的方法验证身份证号
            return elderBasicService.verifyIdCardWithoutPermissionCheck(elderId, idCard);
        } catch (Exception e) {
            // 记录异常
            org.slf4j.LoggerFactory.getLogger(ContactServiceImpl.class)
                .error("验证老人身份证号失败: elderId={}, idCard={}", elderId, idCard, e);
            return false;
        }
    }
}
